﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;

namespace SceneEngine
{
    public class RenderManager
    {
        private Dictionary<string, Model> models =
            new Dictionary<string, Model>();

        private Dictionary<string, BaseObjectRenderer> modelRenderers =
            new Dictionary<string, BaseObjectRenderer>();

        private List<string> usedRenderers = new List<string>();

        public RenderManager()
        {

        }

        public void AddModel(string assetName, Model model)
        {
            if (models.ContainsKey(assetName))
            {
                return;
            }

            models.Add(assetName, model);

            if (modelRenderers.ContainsKey(assetName) == false)
            {
                modelRenderers.Add(assetName, new BaseObjectRenderer(model, assetName));
            }
        }

        public Model GetModel(string assetName)
        {
            return models[assetName];
        }
        
        private void SubmitInstance(BaseObject baseObject)
        {
            modelRenderers[baseObject.ModelPath].SubmitInstance(baseObject);

            if (usedRenderers.Contains(baseObject.ModelPath) == false)
            {
                usedRenderers.Add(baseObject.ModelPath);
            }
        }

        public void BeginRendering()
        {
            List<BaseObject> visibleUnits = EngineGlobals.Scene.GetVisibleObjects();

            // Draw enemies
            foreach (BaseObject baseObject in visibleUnits)
            {
                SubmitInstance(baseObject);

                //DebugShapeRenderer.AddBoundingBox(terrainObject.BoundingBox, Color.Blue);
            }
        }

        public void Render()
        {
            EngineGlobals.GraphicsDevice.BlendState = BlendState.Opaque;

            for (int i = 0; i < usedRenderers.Count; i++)
            {
                modelRenderers[usedRenderers[i]].DrawOpaque();
            }

            EngineGlobals.GraphicsDevice.BlendState = BlendState.NonPremultiplied;
            EngineGlobals.GraphicsDevice.RasterizerState = RasterizerState.CullNone;

            while (usedRenderers.Count > 0)
            {
                modelRenderers[usedRenderers[0]].DrawTransparent();
                modelRenderers[usedRenderers[0]].EndDraw();
                usedRenderers.RemoveAt(0);
            }

            EngineGlobals.GraphicsDevice.BlendState = BlendState.Opaque;
            EngineGlobals.GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
        }

        public void RemoveModel(string modelName)
        {
            if (models.ContainsKey(modelName))
            {
                models.Remove(modelName);
            }
        }
    }
}
